package cn.ccbom.bom.interview.core.design_pattern.singleton;

import cn.ccbom.bom.interview.core.design_pattern.singleton.normal.LocalClientUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.Data;
import lombok.extern.log4j.Log4j2;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Data
@Log4j2
public class Singleton {

    public void create() {
        //org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton
    }

    public static void main(String[] args) {
        int maxThread = 10;
        int activeThread = 100;
        Integer lock = 1;
        //比较10个数据是否一致
        CountDownLatch countDownLatch = new CountDownLatch(activeThread);
        //List<LocalClient> list = Collections.synchronizedList(new LinkedList<>());
        List<LocalClient> list = new LinkedList<>();
        ExecutorService executorService = Executors.newFixedThreadPool(maxThread);
        for (int i = 0; i < activeThread; i++) {
            int finalI = i;
            executorService.execute(() -> {
                try {
                    LocalClient singleton = LocalClientUtil.singleton();
                    synchronized (lock) {
                        list.add(singleton);//线程不安全,多种方式可选
                    }
                    //线程不安全的
                    ThreadUtil.sleep(RandomUtil.randomInt(1,3)* 1000L);
                    log.info("执行完成:{}", finalI);
                } catch (Exception e) {
                    System.out.println("Exception: do something exception");
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        try {
            //@SuppressWarnings("unused")
            countDownLatch.await(100, TimeUnit.SECONDS);
            log.info("完成: {}", list.stream().allMatch(e -> e == list.get(0)));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
